package org.eda.actividad4;

public class SimpleLinkedList<T>  implements ILinkedList<T>{
	
	// Atributos
	private Node<T> first;
	private Node<T> actual;
	public int tamano;

	
	// Constructor
	public SimpleLinkedList() {
		first = null;
		actual = null;
		tamano = 0;
	}

	
	// Metodos publicos
	public void goFirst() {
		actual = first;
	}

	public void goNext() {
		if (actual != null)
			actual = actual.next;
	}

	public void goPrevious() {
		if (first != null) {
			if (first == actual)
				actual = null;
			else {
				Node<T> aux = first;
				while (aux.next != actual) {
					aux = aux.next;
				}
				actual = aux;
			}
		}
	}

	public void goLast() {
		if (first != null) {
			actual = first;
			while (actual.next != null) {
				actual = actual.next;
			}
		}
	}

	public boolean hasNext() {
		return (actual != null);
	}

	public boolean find(T elem) {

		actual = first;
		while ((actual != null) && !(actual.data.equals(elem))){
			actual = actual.next;
		}
		return (actual != null);
	}

	public void insert(T elem) {
		
		Node<T> newNode = new Node<T>(elem);
		if (actual == null) {
			newNode.next = first;
			first = newNode;

		} else {
			newNode.next = actual.next;
			actual.next = newNode;
		}
		tamano = tamano +1;
		actual = newNode;
	}

	public void insertFirst(T elem) {
		Node<T> newNode = new Node<T>(elem);
		newNode.next = first;
		first = newNode;
		actual = first;
		tamano = tamano +1;
	}

	public void insertLast(T elem) {
		Node<T> newNode = new Node<T>(elem);
		this.goFirst();
		if (actual == null) {
			newNode.next = first;
			first = newNode;
		} else {
			while (actual.next != null){
				actual = actual.next;
			}
			actual.next = newNode;
		}
		actual = newNode;
		tamano = tamano +1;
	}


	public void remove(T elem) {
		if (first != null) {
			if (first.data.equals(elem))
				first = first.next;
			else {
				actual = first;
				Node<T> ant = null;
				while ((actual.next != null) && !(actual.data.equals(elem))) {
					ant = actual;
					actual = actual.next;
				}
				if (actual.data.equals(elem))
					ant.next = actual.next;
			}
		}
		actual = first;
		tamano = tamano -1;
	}
	
	public void remove() {

		Node<T> ant = first;
		if (actual != null) {
			if (ant == actual)
				first = first.next;
			else {
				while (ant.next != actual)
					ant = ant.next;
				ant.next = actual.next;
			}
			actual = actual.next;
			tamano = tamano -1;
		}
	}

	public T remove(int index) {
		// Pre: Hay al menos "index" nodos

		actual = first;
		T dato;
		if (index == 1) {
			dato = first.data;
			first = first.next;
		} else {
			for (int i = 2; i < index; i++)
				actual = actual.next;
			dato = actual.next.data;
			actual.next = actual.next.next;

		}
		dato = actual.data;
		tamano = tamano-1;
		actual = first;
		return dato;
	}

	public T get() {
		// Pre: actual apunta a algun nodo
		
		return actual.data;
	}

	public T get(int index) {
		actual = first;
		int cont = 1;
		while (cont < index && actual.next != null) {
			actual = actual.next;
			cont = cont + 1;
		}
		return actual.data;
	}

	public boolean isEmpty() {
		return (first == null);
	}

}
